from khronos.utils.parsing.lexer import Token
from khronos.utils.parsing.bnf import Choice, Sequence, Optional, Repeat

class Parser(object):
    def __init__(self, nonterminals=None, start="start", lexer=None):
        self.lexer = lexer
        self.start = start
        self.nonterminals = dict((nt.__name__, nt) for nt in nonterminals)
        
    def add(self, nonterminal):
        self.nonterminals[nonterminal.__name__] = nonterminal
        
    def parse(self, text):
        self.lexer.init(text)
        start = self.nonterminals[self.start]
        parse = self.parse_fnc[start.__class__]
        result = parse(self, start)
        if not self.lexer.finished():
            raise Exception("unparsed input detected")
        return result
        
    def parse_token(self, token):
        t = self.lexer.get_next()
        if t.type != token.type:
            self.lexer.put_back(t)
            return False, None
        return True, t
        
    def parse_choice(self, choice):
        for option in choice:
            parse_fnc = self.parse_fnc[option.__class__]
            success, result = parse_fnc(self, option)
            if success:
                
        raise NotImplementedError()
        
    def parse_sequence(self):
        raise NotImplementedError()
    
    def parse_optional(self):
        raise NotImplementedError()
    
    def parse_repeat(self):
        raise NotImplementedError()
    
    parse_fnc = {Token: parse_token,
                 Choice: parse_choice,
                 Sequence: parse_sequence,
                 Optional: parse_optional,
                 Repeat: parse_repeat}
                  
    